Go实战

您所在的位置:网站首页 go http封装 Go实战

Go实战

2023-12-01 17:39| 来源: 网络整理| 查看: 265

在高并发场景下,为了降低系统压力,都会使用一种让请求排队处理的机制。本文就介绍在Go中是如何实现的。

一、http请求的顺序处理方式

首先,我们看下正常的请求处理逻辑。 客户端发送请求,web server接收请求,然后就是处理请求,最后响应给客户端这样一个顺序的逻辑。如下图所示: 01-正常请求.png

代码实现如下:

package main import ( "fmt" "net/http" ) func main() { myHandler := MyHandler{} http.Handle("/", &myHandler) http.ListenAndServe(":8080", nil) } type MyHandler struct { } func (h *MyHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { w.Write([]byte("Hello Go")) }

在浏览器中输入 http://localhost:8080/,就能在页面上显示出“Hello Go”的页面来。

通常情况下,大家在开发web系统的时候,一般都是这么处理请求。接下来我们看在高并发下如何实现让请求进行排队处理。

二、http请求的异步处理方式--排队处理

让http请求进入到队列,我们也称为异步处理方式。其基本思想就是将接收到的请求的上下文(即request和response)以及处理逻辑包装成一个工作单元,然后将其放到队列,然后该工作单元等待消费的工作线程处理该job,处理完成后再返回给客户端。 流程如下图: 02-队列请求处理.png

该实现中会有三个关键的元素:工作执行单元、队列、消费者。下面我们逐一看下各自的职责及实现。

工作单元

该工作单元主要是封装请求的上下文信息(request和response)、请求的处理逻辑以及该工作单元是否被执行完成的状态。

请求的处理逻辑实际上就是原来在顺序处理流程中的具体函数,如果是mvc模式的话就是controller里的一个具体的action。

在Go中实现通信的方式一般是使用通道。所以,在工作单元中有一个通道,当该工作单元执行完具体的处理逻辑后,就往该通道中写入一个消息,以通知主协程该次请求已完成,可以返回给客户端了。

所以,一个http请求的处理逻辑看起来就像是下面这样:

func (h *MyHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { 将w和r包装成工作单元job 将job入队 等待job执行完成 本次请求处理完毕 }

下面我们看下工作单元的具体实现,这里我们将其定义为一个Job结构体:

type Job struct { DoneChan chan struct{} handleJob func(j FlowJob) error //具体的处理逻辑 }

Job结构体中有一个handleJob,其类型是一个函数,即处理请求的逻辑部分。DoneChan通道用来让该单元进行阻塞等待,并当handleJob执行完毕后发送消息通知的。

下面我们再看看该Job的相关行为:

// 消费者从队列中取出该job时 执行具体的处理逻辑 func (job *Job) Execute() error { fmt.Println("job start to execute ") return job.handleJob(job) } // 执行完Execute后,调用该函数以通知主线程中等待的job func (job *Job) Done() { job.DoneChan


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3